<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@include file="/WEB-INF/webpage/common/taglibs.jspf"%>
<!DOCTYPE html>
<html>
  <head>
  	<title>web 文件管理</title>
    <meta name="decorator" content="form"/>
    <html:css name="bootstrap-fileinput"/>
    <html:css name="simditor"/>
    <%--webuploader--%>
    <link type="text/css" rel="stylesheet" href="${staticPath }/vendors/webuploader/webuploader.css"/>
	<link type="text/css" rel="stylesheet" href="${staticPath}/vendors/webuploader/drag/style.css" />
	<link type="text/css" rel="stylesheet" href="${staticPath}/vendors/webuploader/cropper/css/cropper.css" />
	<link type="text/css" rel="stylesheet" href="${staticPath}/vendors/webuploader/cropper/css/style.css" />
	<script type="text/javascript" src="${staticPath}/vendors/webuploader/cropper/js/cropper.js" ></script>
	<script type="text/javascript" src="${staticPath}/vendors/webuploader/webuploader.min.js"></script>
	<%-- <script type="text/javascript" src="${staticPath}//vendors/webuploader/webuploader.nolog.min.js"></script> --%>
</head>
<body>
	<%-- <div class="portlet-body">
		<p>文件上传标签</p>
		<html:display></html:display>
		<form:webuploader path="file" nested="false"/>
	</div> --%>
	<div id="wrapper">
		<!--拖拽上传-->
        <div id="container">
            <!--头部，相册选择和格式选择-->
            <div id="uploader">
                <div id="queueList" class="queueList">
                    <div id="dndArea" class="placeholder">
                       <div id="filePicker"></div>
                        <p>或将照片拖到这里，单次最多可选300张</p>
                    </div>
                </div>
                <div id="statusBar" class="statusBar" style="display:none;">
                    <div id="progress" class="progress">
                        <span id="text" class="text">0%</span>
                        <span id="percentage" class="percentage"></span>
                    </div><div id="info" class="info"></div>
                    <div class="btns">
                        <div id="filePicker2"></div><div id="uploadBtn" class="uploadBtn">开始上传</div>
                    </div>		                    
                </div>
            </div>
       </div>
  </div>
  <script type="text/javascript">
 $(function(){
	 	var self = this;
	  	var $webUpload = WebUploader;
	  	var $fileCount = 0;
	  	var $fileSize = 0;
	  	var $uploadWrap = $('#uploader');
	  	var $placeHolder = $('#dndArea');
	  	var $statusBar = $uploadWrap.find( '#statusBar' );
	  	var $uploadBtn = $uploadWrap.find( '#uploadBtn' );
	  	var $fileArray = new Array();
	  	var $file,$fileMd5,$fileName;
	  	var $uploadCount = 0;
	  	var $queues = $( '<ul class="filelist"></ul>' ).appendTo( $uploadWrap.find( '#queueList' ) )
	  	var $statusBar = $uploadWrap.find( '#statusBar' );// 状态栏，包括进度和控制按钮
	  	var $progress = $statusBar.find( '#progress' ).hide();//总进度条
	  	var $info = $statusBar.find( '#info' );//文件总体选择信息
	  	var $ratio = window.devicePixelRatio || 1;// 优化retina, 在retina下这个值是2
	  	var $thumbnailWidth = 110 * $ratio;//缩略图宽度
	  	var $thumbnailHeight = 110 * $ratio;//缩略图高度
        var $state = 'pedding';// 可能有pedding, ready, uploading, confirm, done.
        var $percentages = {};// 所有文件的进度信息，key为file id
        var $filePercent = {};//存放所有文件的上传进度，通过hash值标识
        var $formData = {};
        var $fileMd5Arr = {};//存放文件的MD5值
        
        var dndArea = '#dndArea';
        var filePicker = '#filePicker';
	  	var filePicker2 = '#filePicker2';
        
     	/**判断浏览器是否支持图片的base64*/ 
		var isSupportBase64 = ( function() {
            var data = new Image();
            var support = true;
            data.onload = data.onerror = function() {
                if( this.width != 1 || this.height != 1 ) {
                    support = false;
                }
            }
            data.src = "";
            return support;
        } )();
        
		/**检测是否支持旋转*/
        var supportTransition = (function(){
            var s = document.createElement('p').style,
                r = 'transition' in s ||
                        'WebkitTransition' in s ||
                        'MozTransition' in s ||
                        'msTransition' in s ||
                        'OTransition' in s;
            s = null;
            return r;
        })();
	  	
	  	/**注册webuploader的服务，必须先注册，才能初始化，否则导致无效*/
	  	$webUpload.Uploader.register({
	  		"add-file":"addFile",
	        "before-send-file": "beforeSendFile",//整个文件上传前
	        "before-send": "beforeSend",  //每个分片上传前
	        "after-send-file": "afterSendFile",  //分片上传完毕
	  	},{
	  		addFile:function(files){
	  		},
	  		beforeSendFile: function(file){
				return beforeSendFile(file);
		  	},
	  		beforeSend: function(file){
	  			return beforeSend(file,this);
		  	},
	  		afterSendFile: function(file){
	  			afterSendFile(file);
		  	},
	  	});
	  	
	  	/**初始化webuploader组件*/
	  	var uploader = $webUpload.create({
			swf:'${staticPath}/vendors/webuploader/Uploader.swf',
			dnd:dndArea,//拖拽的容器
			disableGlobalDnd:true,
			paste:dndArea,
			pick:{
				id:filePicker,//主键名称
				label:'选择图片',//按钮名称，优先选择innerHTML
				innerHTML:'选择图片',//按钮名称
				multiple:true//开启多文件选择
			},
			server:'${adminPath}/sys/attachment/saveFile',
			auto:false,//自动上传
			prepareNextFile:true,
			chunked: true,//开启分片上传
			chunkSize:5242880,//分片大小
			chunkRetry:2,//网络问题出错，允许上传次数
			threads:3,//允许同时最大上传进程数
			//formData:$formData,//文件上传请求的参数表
			fileVal:'file', //设置文件上传域的name
			method :'POST',//文件上传方式，POST或者GET
			sendAsBinary:false,//是否已二进制的流的方式发送文件
			fileNumLimit:3000,//允许上传文件的总数量 
			//fileSizeLimit:524288000,//验证文件总大小是否超出限制
			//fileSingleSizeLimit:52428800,//验证单个文件大小是否超出限制
			duplicate:false,//根据文件名字、文件大小和最后修改时间来生成hash Key.
			//disableWidgets {String, Array} [可选] [默认值：undefined] 默认所有 Uploader.register 了的 widget 都会被加载，如果禁用某一部分，请通过此 option 指定黑名单
			accept:{},
			thumb:thumb,
			compress:compress
		});
	  	
	  	/**定义图片压缩质量*/
	  	var thumb = {
			width: 110,
		    height: 110,
		    // 图片质量，只有type为`image/jpeg`的时候才有效。
		    quality: 70,
		    // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.
		    allowMagnify: true,
		    // 是否允许裁剪。
		    crop: true,
		    // 为空的话则保留原有图片格式。
		    // 否则强制转换成指定的类型。
		    type: 'image/jpeg'
		}
		
	  	/**定义图片压缩信息*/
		var compress = {
			width: 1600,
		    height: 1600,
		    // 图片质量，只有type为`image/jpeg`的时候才有效。
		    quality: 90,
		    // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.
		    allowMagnify: false,
		    // 是否允许裁剪。
		    crop: false,
		    // 是否保留头部meta信息。
		    preserveHeaders: true,
		    // 如果发现压缩后文件大小比原来还大，则使用原来图片
		    // 此属性可能会影响图片自动纠正功能
		    noCompressIfLarger: false,
		    // 单位字节，如果图片大小小于此值，不会采用压缩。
		    compressSize: 0
		}
	  	
	  	/**分块上传前执行操作*/
	  	function beforeSendFile(file){
	  		var fileHash = file.__hash;
			var deferred = $webUpload.Deferred();
			//计算文件的唯一标记fileMd5，用于断点续传
			var md5 = (new WebUploader.Uploader()).md5File(file, 0, 10 * 1024 * 1024);
			md5.progress(function (percentage) {
                $('#' + file.id).find('p.state').text('正在读取文件信息...');
            }).then(function (val) {
                $('#' + file.id).find('p.state').text('成功获取文件信息...');
                $fileMd5 = val;
                $fileMd5Arr[fileHash] = val;
                //获取文件信息后进入下一步
                deferred.resolve();
            });
            $fileName = file.name;
            $file = file;
            return deferred.promise();
	  	}
	  	
	  	/**分块上传*/
	  	var beforeSend = function(block,obj){
	  		var hash = block.file.__hash;
	  		var fileName = block.file.name;
	  		var fileMd5 = $fileMd5Arr[hash];
	  		var progressRate = $filePercent[hash];
			var deferred = $webUpload.Deferred();
			//发送请求，执行分块上传
			$.ajax({
                type: 'POST',
                url: "${adminPath}/sys/attachment/mergeOrCheckChunks",  //ajax验证每一个分片
                cache: false,
                async: false,  // 同步
                timeout: 1000,//超时则返回错误
                data: {
                    isMerge : false,//合并还是分块上传
                    fileName: fileName,
                    fileHash: hash,
                    progressRate: progressRate,
                    fileMd5: fileMd5,  //文件唯一标记
                    chunk: block.chunk,  //当前分块下标
                    chunkSize: block.end - block.start//当前分块大小
                },
              	dataType:"json",               
                success: function (res) {
                    if (res.data) {
                        deferred.reject();//分块存在，跳过
                    } else {
                        deferred.resolve();//分块不存在或不完整，重新发送该分块内容
                    }
                }
            });
			//更新参数
			obj.owner.options.formData.fileMd5 = $fileMd5;
			obj.owner.options.formData.chunk = block.chunk;
			obj.owner.options.formData.fileHash = hash;
            deferred.resolve();
            return deferred.promise();
	  	}
	  	
	  	/**分块上传结束之后执行操作*/
	  	var afterSendFile = function(file){
	  		/**上传结束之后隐藏进度条*/
	  		var hash = file.__hash;
	  		var fileName = file.name;
	  		var fileMd5 = $fileMd5Arr[hash];
	  		var $li = $('#'+file.id);
			var $percent = $li.find('.progress span');
			$li.find('.progress').css("opacity",0);
			var ss = "ssss";
			var forms = {billId:1,relateTable:ss,relateFeild:ss};
			var obj = {
                isMerge : true,//合并还是分块上传
                fileName: fileName,
                fileHash: hash,
                fileMd5: fileMd5
            }
			obj = Object.assign(obj,forms);
			//如果分块上传成功，则通知后台合并分块
            $.ajax({
                type: 'POST',
                url: '${adminPath}/sys/attachment/mergeOrCheckChunks',
                data: obj,
                success: function (data) {
                	$uploadCount++; //每上传完成一个文件 count+1
                    if ($uploadCount <= $fileArray.length - 1) {
                    	//上一个文件上传成功后,继续执行下一个文件上传
                        //uploader.upload($fileArray[$uploadCount].id);
                    }
                    //合并成功之后的操作
                }
            });
	  	}
	  
	 	/**初始化继续添加按钮*/
        uploader.addButton({
            id: filePicker2,
            label: '继续添加'
        });
	  	
	    /**当文件被加入队列以后触发*/
        uploader.onFileQueued = function( file ) {
        	$fileArray.push(file);
        	$fileCount++;
        	$fileSize += file.size;
            if ( $fileCount === 1 ) {
                $placeHolder.addClass( 'element-invisible' );
                $statusBar.show();
            }
            addFile(file);
            setState( 'ready' );
            updateTotalProgress();
	    }
	    
        /**选择一批文件时候的队列*/
        uploader.onFilesQueued = function(files){
        	var fileHashs = new Array();
        	$.each(files,function(index,item){
        		fileHashs.push(item.__hash);
        	});
        	//获取文件在后台的进度
        	$.ajax({
	            type: "POST",
	            url: '${adminPath}/sys/attachment/getFilesProgress',  //先检查该文件是否上传过，如果上传过，上传进度是多少
	            data: {fileHashs: fileHashs.join(',')},
	            cache: false,
	            async: false,  // 同步
	            dataType:"json",
	            success: function (res) {
	            	$filePercent = $.extend({}, $filePercent, res);
	            }
        	});
        }
	    
      	/**当文件被移除队列后触发*/
        uploader.onFileDequeued = function( file ) {
            removeFile( file );
        };
	    
      	//文件上传过程中创建进度条实时显示
      	uploader.onUploadProgress = function (file, percentage) {
      		var progressPercent = Math.round(percentage * 100);
      		var $li = $('#'+file.id);
			var $percent = $li.find('.progress span');
			$li.find('.progress').css("opacity",1);
			
			$percent.text(progressPercent + '%');
            $percent.css( 'width', percentage * 100 + '%' );
            $percentages[ file.id ][ 1 ] = percentage;
            $filePercent[file.__hash] = percentage;
            updateTotalProgress();
      	}
      	
      	//上传前发送数据
      	uploader.onUploadBeforeSend = function(obj, data, headers){
      		var forms = {billId:1,relateTable:'sss',relateFeild:'dddd'};
      		data.formData = JSON.stringify(forms);
      	}
      	
      	//文件上传成功
      	uploader.onUploadSuccess = function (file) {
      		//debugger
      	}
      	
      	//上传出错后执行的方法
        uploader.onUploadError = function (file) {
            //debugger
        }

        //文件上传成功失败都会走这个方法
        uploader.onUploadComplete = function (file) {
        	//debugger
        }

        uploader.on('all', function (type) {
        	var stats;
            switch( type ) {
                case 'uploadFinished'://当所有文件上传结束时触发
                    setState( 'confirm' );
                    break;

                case 'startUpload'://当开始上传流程时触发
                    setState( 'uploading' );
                    break;

                case 'stopUpload'://当开始上传流程暂停时触发
                    setState( 'paused' );
                    break;
            }
        });
        
      	/**文件错误*/
        uploader.onError = function( code ) {
      		if(code=='Q_EXCEED_NUM_LIMIT'){
      			alert('Eroor: 上传文件的总数量超出了限制');
      		}else if(code=='Q_EXCEED_SIZE_LIMIT'){
      			alert('Eroor: 上传文件的总大小超出限制');
      		}else if(code=='Q_TYPE_DENIED'){
      			alert('Eroor: 上传文件的类型不正确');
      		}else if(code=='F_EXCEED_SIZE'){
      			alert('Eroor: 单个文件的大小超出限制');
      		}
        };
      	
        /**添加文件，这里做文件展示的相关操作，包含文件删除、旋转、浏览等*/
        function addFile(file){
        	 var $li = $( '<li id="' + file.id + '">' +
	                    '<p class="title">' + file.name + '</p>' +
	                    '<p class="imgWrap"></p>'+
	                    '<p class="progress"><span></span></p>' +
	                    '</li>' );
             var $btns = $('<div class="file-panel">' +
                 '<span class="cancel">删除</span>' +
                 '<span class="rotateRight">向右旋转</span>' +
                 '<span class="rotateLeft">向左旋转</span></div>').appendTo( $li );
             var $prgress = $li.find('p.progress span');
             var $wrap = $li.find( 'p.imgWrap' );
             var $info = $('<p class="error"></p>');
             var showError = function( code ) {
                switch( code ) {
                    case 'exceed_size':
                        text = '文件大小超出';
                        break;

                    case 'interrupt':
                        text = '上传暂停';
                        break;

                    default:
                        text = '上传失败，请重试';
                        break;
                }
                $info.text( text ).appendTo( $li );
            };
            
            //判断文件是否有效
            if ( file.getStatus() === 'invalid' ) {
                showError( file.statusText );
            } else {
            	showFileImg(file,$wrap);
            }
            
            /**鼠标进入事件*/
            $li.on( 'mouseenter', function() {
                $btns.stop().animate({height: 30});
            });

            /**鼠标离开事件*/
            $li.on( 'mouseleave', function() {
                $btns.stop().animate({height: 0});
            });
            
            /**文件状态发生改变事件*/
            file.on('statuschange', function( cur, prev ) {
                if ( prev === 'progress' ) {
                    $prgress.hide().width(0);
                } else if ( prev === 'queued' ) {
                    $li.off( 'mouseenter mouseleave' );
                    $btns.remove();
                }
                // 成功
                if ( cur === 'error' || cur === 'invalid' ) {
                    console.log( file.statusText );
                    showError( file.statusText );
                    $percentages[ file.id ][ 1 ] = 1;
                } else if ( cur === 'interrupt' ) {
                    showError( 'interrupt' );
                } else if ( cur === 'queued' ) {
                    $percentages[ file.id ][ 1 ] = 0;
                } else if ( cur === 'progress' ) {
                    $info.remove();
                    $prgress.css('display', 'block');
                } else if ( cur === 'complete' ) {
                    $li.append( '<span class="success"></span>' );
                }
                $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
            });

            /**按钮组点击事件*/
            $btns.on( 'click', 'span', function() {
                var index = $(this).index(),deg;
                switch ( index ) {
                    case 0:
                        removeFile( file );
                        return;
                    case 1:
                        file.rotation += 90;
                        break;
                    case 2:
                        file.rotation -= 90;
                        break;
                }
                if ( supportTransition ) {
                    deg = 'rotate(' + file.rotation + 'deg)';
                    $wrap.css({
                        '-webkit-transform': deg,
                        '-mos-transform': deg,
                        '-o-transform': deg,
                        'transform': deg
                    });
                } else {
                    $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
                }
            });
            $li.appendTo( $queues );
        }
        
        /**显示文件缩率图*/
        function showFileImg(file,$wrap){
        	$wrap.text( '预览中' );
            uploader.makeThumb( file, function( error, src ) {
                var img;
                //TODO 根据文件扩展名显示图片
                if ( error ) {
                    $wrap.text( '不能预览' );
                    return;
                }
                if( isSupportBase64 ) {
                    img = $('<img src="'+src+'">');
                    $wrap.empty().append( img );
                } else {
                    $.ajax('../../server/preview.php', {
                        method: 'POST',
                        data: src,
                        dataType:'json'
                    }).done(function( response ) {
                        if (response.result) {
                            img = $('<img src="'+response.result+'">');
                            $wrap.empty().append( img );
                        } else {
                            $wrap.text("预览出错");
                        }
                    });
                }
            }, $thumbnailWidth, $thumbnailHeight );

            $percentages[ file.id ] = [ file.size, 0 ];
            file.rotation = 0;
        }
            
     	/**负责文件视图view的销毁*/
        function removeFile(file) {
     		var index = $fileArray.indexOf(file);
     		$fileArray.splice(index);
            $fileCount--;
            $fileSize -= file.size;
            if ( !$fileCount ) {
                setState( 'pedding' );
            }
            
            var $li = $('#'+file.id);
            delete $percentages[ file.id ];
            updateTotalProgress();
            $li.off().find('.file-panel').off().end().remove();
            
            updateTotalProgress();
        }
		
		/**更新总的进度条*/
        function updateTotalProgress() {
            var loaded = 0,
                total = 0,
                spans = $progress.children(),
                percent;

            $.each( $percentages, function( k, v ) {
                total += v[ 0 ];
                loaded += v[ 0 ] * v[ 1 ];
            } );
            percent = total ? loaded / total : 0;
            spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' );
            spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' );
            updateStatus();
        }

		/**更新文件状态*/
        function updateStatus() {
            var text = '', stats;
            if ( $state === 'ready' ) {
                text = '选中' + $fileCount + '个文件，共' +
                        WebUploader.formatSize( $fileSize ) + '。';
            } else if ( $state === 'confirm' ) {
                stats = uploader.getStats();
                if ( stats.uploadFailNum ) {
                    text = '已成功上传' + stats.successNum+ '个文件，'+
                        stats.uploadFailNum + '个文件上传失败，<a class="retry" href="#">重新上传</a>失败文件或<a class="ignore" href="#">忽略</a>'
                }
            } else {
                stats = uploader.getStats();
                text = '共' + $fileCount + '个（' +
                        WebUploader.formatSize( $fileSize )  +
                        '），已上传' + stats.successNum + '个';
                if ( stats.uploadFailNum ) {
                    text += '，失败' + stats.uploadFailNum + '个';
                }
            }
            $info.html( text );
        }

		/**设置文件状态*/
        function setState( val ) {
            var file, stats;
            if ( val === $state ) {
                return;
            }
            $uploadBtn.removeClass( 'state-' + $state );
            $uploadBtn.addClass( 'state-' + val );
            $state = val;
            switch ( $state ) {
                case 'pedding':
                    $placeHolder.removeClass( 'element-invisible' );
                    $queues.hide();
                    $statusBar.addClass( 'element-invisible' );
                    uploader.refresh();
                    break;
                case 'ready':
                    $placeHolder.addClass( 'element-invisible' );
                    $( filePicker2 ).removeClass( 'element-invisible');
                    $queues.show();
                    $statusBar.removeClass('element-invisible');
                    uploader.refresh();
                    break;
                case 'uploading':
                    $( filePicker2 ).addClass( 'element-invisible' );
                    $progress.show();
                    $uploadBtn.text( '暂停上传' );
                    break;
                case 'paused':
                    $progress.show();
                    $uploadBtn.text( '继续上传' );
                    break;
                case 'confirm':
                    $progress.hide();
                    $( filePicker2 ).removeClass( 'element-invisible' );
                    $uploadBtn.text( '开始上传' );
                    stats = uploader.getStats();
                    if ( stats.successNum && !stats.uploadFailNum ) {
                        setState( 'finish' );
                        return;
                    }
                    break;
                case 'finish':
                    stats = uploader.getStats();
                    if ( stats.successNum ) {
                        //alert( '上传成功' );
                    } else {
                        // 没有成功的图片，重设
                        state = 'done';
                        location.reload();
                    }
                    break;
            }
            updateStatus();
        }
        
        /**上传按钮，执行文件上传*/
        $uploadBtn.on('click', function() {
        	//从后台获取文件上传进度，并加入map里面
        	if ( $(this).hasClass( 'disabled' ) ) {
                return false;
            }
            if ( $state === 'ready' ) {
                //uploader.upload($fileArray[0].id);
                uploader.upload();
            } else if ( $state === 'paused' ) {
                uploader.upload();
            } else if ( $state === 'uploading' ) {
                uploader.stop(true);
            }
        });
        
        $info.on( 'click', '.retry', function() {
            uploader.retry();
        } );

        $info.on( 'click', '.ignore', function() {
            alert( 'todo' );
        } );

        /**设置上传按钮样式*/
        $uploadBtn.addClass( 'state-' + $state );
        /**更新总的进度条*/
        updateTotalProgress();
  });
  </script>
</body>
</html>
